/**
 * 
 */
package model.facade.persistence.mysql;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import model.core.torneo.Calendario;
import model.core.torneo.Classifica;
import model.core.torneo.Commissione;
import model.core.torneo.Gara;
import model.core.torneo.Torneo;
import model.core.utente.Commissario;
import model.core.utente.Giocatore;
import model.core.utente.GiocatoreInterface;
import model.core.utente.Squadra;
import model.facade.persistence.TorneoDAO;

/**
 * @author Giuseppe Fusco (fusgius19@gmail.com)
 *
 */
public class TorneoDAO_MySQL extends MySQLDomainDAO implements TorneoDAO{

	/**
	 * @param dbms
	 * @throws SQLException 
	 */
	public TorneoDAO_MySQL(MySQLDBMS dbms) throws SQLException {
		super(dbms);
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#insert(java.lang.Object)
	 */
	@Override
	public boolean insert(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Torneo){
			try {
				synchronized (obj) {
					Torneo t = (Torneo)obj;
					PreparedStatement p = mys.getPreparedStatement("insert into torneo(nome,tipologia,numero_edizione,anno_svolgimento" +
							",is_singolo,stato_torneo,vincitore,max_partecipanti,min_partecipanti) values(?,?,?,?,?,?,?,?,?)");
					p.setString(1, t.getNome());
					p.setString(2, t.getTipologia());
					p.setInt(3, t.getNumero_edizione());
					p.setInt(4, t.getAnno_svolgimento());
					p.setInt(5, t.isSingolo()?1:0);
					p.setString(6, t.getStato());
					int vin = MySQLUtentiQueryUtility.getIdGiocatore(t.getVincitore(), mys);
					if(vin!=-1)p.setInt(7, vin);
					else p.setNull(7, java.sql.Types.NULL);
					p.setInt(8, t.getMaxComponenti());
					p.setInt(9, t.getMinComponenti());
					p.execute();
					p.close();
					int tid = MySQLTorneiQueryUtility.getIdTorneoByNome(t.getNome(), mys);
					if(tid!=-1){
						for(GiocatoreInterface g: t.getClassifica().getGiocatori()){
							if(g instanceof Giocatore){
								if(MySQLUtentiQueryUtility.getIdGiocatorebyIdStudente((Giocatore) g, mys)==-1){
									return false;
								}
							}else if(g instanceof Squadra){
								if(MySQLUtentiQueryUtility.getIdSquadraByNome(((Squadra) g).getNome(), mys)==-1){
									return false;
								}
							}

						}
						for(Commissario com: t.getCommissione().getCommissione()){
							if(MySQLUtentiQueryUtility.getIdStudente(com.getMatricola(), com.getPassword(), mys)==-1)
								return false;
						}
						for(GiocatoreInterface g: t.getClassifica().getGiocatori()){
							addGiocatoreToTorneo(g, t);
						}
						for(Commissario com: t.getCommissione().getCommissione()){
							addCommissarioToTorneo(com, t);
						}
						return true;
					}
					else
						return false;	
				}
			} catch (Exception e) {
				// TODO: handle exception
				return false;
			}
		}
		else
			return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#delete(java.lang.Object)
	 */
	@Override
	public boolean delete(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Gara){
			Torneo g = (Torneo)obj;
			try {
				mys.executeUpdate("delete from torneo where nome=\""+g.getNome()+"\"");
				return true;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		}else return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#update(java.lang.Object)
	 */
	@Override
	public boolean update(Object obj) {
		// TODO Auto-generated method stub
		if(obj instanceof Torneo){
			try {
				synchronized (obj) {
					Torneo t = (Torneo)obj;
					ResultSet r = mys.getResult("select * from torneo where nome=\""+t.getNome()+"\"");
					if(r.first()){
						r.updateString("nome", t.getNome());
						r.updateInt("numero_edizione", t.getNumero_edizione());
						r.updateInt("anno_svolgimento", t.getAnno_svolgimento());
						r.updateString("tipologia", t.getTipologia());
						r.updateString("stato_torneo", t.getStato());
						r.updateInt("is_singolo", t.isSingolo()?1:0);
						r.updateInt("max_partecipanti", t.getClassifica().getMaxComponenti());
						r.updateInt("min_partecipanti", t.getClassifica().getMinComponenti());
						int idvin = MySQLUtentiQueryUtility.getIdGiocatore(t.getVincitore(), mys);
						if(idvin!=-1)r.updateInt("vincitore", idvin);
						else r.updateNull("vincitore");
						r.updateRow();
						r.close();
						return true;
					}else
						return false;	
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
		}else
			return false;
	}

	/* (non-Javadoc)
	 * @see model.facade.persistence.PersistenceCommand#retrieve(java.lang.Object[])
	 */
	@Override
	public Object retrieve(Object... properties) {
		// TODO Auto-generated method stub
		if(properties.length==1 && properties[0] instanceof String){
			Torneo t = MySQLTorneiQueryUtility.getTorneoByNome((String) properties[0], mys);
			t.setClassifica(getClassificaByTorneo(t));
			t.setCalendario(getCalendarioByTorneo(t));
			t.setCommissione(getCommissioneByTorneo(t));
			return t;
		}else
			return null;
	}
	
	public void removeCommissarioFromTorneo(Commissario co, Torneo torneo) throws SQLException{
		int id = MySQLUtentiQueryUtility.getIdStudente(co.getMatricola(), co.getPassword(), mys);
		mys.executeUpdate("delete from commissione where (torneo="+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+" and commissario="+id+")");
		ResultSet r = mys.getResult("select * from commissione where commissario="+id);
		if(!r.first()){
			mys.executeUpdate("update studente set tipo=\"STUDENTE\" where idstudente="+id);
		}
		r.close();
	}
	
	public void addCommissarioToTorneo(Commissario co, Torneo torneo) throws SQLException{
		mys.executeUpdate("insert into commissione(torneo,commissario) values("+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+","+MySQLUtentiQueryUtility.getIdStudente(co.getMatricola(), co.getPassword(), mys)+")");
		mys.executeUpdate("update studente set tipo=\"COMMISSARIO\" where idstudente="+MySQLUtentiQueryUtility.getIdStudente(co.getMatricola(), co.getPassword(), mys));
	}

	public void addGiocatoreToTorneo(GiocatoreInterface gi, Torneo torneo) throws SQLException{
		mys.executeUpdate("insert into classifica(torneo,giocatore) values("+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+","+
	((gi instanceof Giocatore)?
			MySQLUtentiQueryUtility.getIdGiocatorebyIdStudente((Giocatore) gi, mys)
			:
				MySQLUtentiQueryUtility.getIdSquadraByNome(((Squadra)gi).getNome(), mys))+")");
	}

	public void removeGiocatoreFromTorneo(GiocatoreInterface gi, Torneo torneo) throws SQLException{
		mys.executeUpdate("delete from classifica where (torneo="+MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys)+" and giocatore="+
	((gi instanceof Giocatore)?
			MySQLUtentiQueryUtility.getIdGiocatorebyIdStudente((Giocatore) gi, mys):
				MySQLUtentiQueryUtility.getIdSquadraByNome(((Squadra)gi).getNome(), mys)
			)+")");
	}
	
	public Classifica getClassificaByTorneo(Torneo torneo){
		int tid = MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys);
		if(tid!=-1){
			try {
				ResultSet rt = mys.getResult("select max_partecipanti,min_partecipanti, is_singolo from torneo where idtorneo="+tid);
				if(rt.first()){
					Classifica c = new Classifica(rt.getInt(1), rt.getInt(2));
					ResultSet r = mys.getResult("select * from classifica where torneo="+tid);
					while(r.next()){
						c.addGiocatore(MySQLUtentiQueryUtility.getGiocatoreByIdGiocatore(r.getInt("giocatore"), mys), rt.getInt(3)==1?true:false);
					}
					return c;
				}
				else
					return null;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				return null;
			}
		}else
			return null;
	}
	
	public Commissione getCommissioneByTorneo(Torneo torneo){
		int tid = MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys);
		if(tid!=-1){
			try {
				Commissione c = new Commissione();
				ResultSet r = mys.getResult("select * from commissione where torneo="+tid);
				while(r.next()){
					c.addCommissario((Commissario) MySQLUtentiQueryUtility.getStudenteByIdStudente(r.getInt("commissario"), mys));
				}
				return c;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				return null;
			}
		}else
			return null;
	}
	
	public Calendario getCalendarioByTorneo(Torneo torneo){
		int tid = MySQLTorneiQueryUtility.getIdTorneoByNome(torneo.getNome(), mys);
		if(tid!=-1){
			try {
				Calendario c = new Calendario();
				ResultSet r = mys.getResult("select * from calendario where torneo="+tid);
				while(r.next()){
					c.addGara(MySQLTorneiQueryUtility.getGaraById(r.getInt("gara"), mys), MySQLUtentiQueryUtility.getStudenteByIdStudente(r.getInt("arbitro"), mys));
				}
				return c;
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				return null;
			}
		}else
			return null;
	}
	
	public List<Torneo> load(String text) throws SQLException{
		List<Torneo> list = new ArrayList<Torneo>();
		ResultSet r = mys.getResult("select * from torneo where (nome like\"%"+text+"%\" or tipologia like\"%"+text+"%\" or " +
				"numero_edizione like\"%"+text+"%\" or anno_svolgimento like\"%"+text+"%\" or stato_torneo like\"%"+text+"%\" or max_partecipanti like\"%"+text+"%\" or " +
				"min_partecipanti like\"%"+text+"%\")");
		while(r.next()){
			list.add((Torneo) retrieve(r.getString("nome")));
		}
		r.close();
		return list;
	}
	

}
